package com.omega.exam.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.omega.exam.Exception.BaseException;
import com.omega.exam.entity.*;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.omega.exam.mapper.*;
import com.omega.exam.service.PaperService;
import com.omega.exam.vo.AiPaperVo;
import com.omega.exam.vo.PaperVo;
import com.omega.exam.vo.RuleVo;
import jakarta.annotation.Resource;
import jodd.bean.BeanUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * 试卷服务实现类
 */
@Slf4j
@Service
public class PaperServiceImpl extends ServiceImpl<PaperMapper, Paper> implements PaperService {
    @Resource
    private PaperMapper paperMapper;
    @Resource
    private QuestionMapper questionMapper;
    @Resource
    private QuestionChoiceMapper questionChoiceMapper;
    @Resource
    private QuestionAnswerMapper questionAnswerMapper;
    @Resource
    private PaperQuestionMapper paperQuestionMapper;


    public Paper getdetailById(Integer id) {
        Paper paper = paperMapper.selectById(id);
        List<Question> list = questionMapper.getByPId(id);
        for (Question question : list) {
            LambdaQueryWrapper<QuestionChoice> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(QuestionChoice::getQuestionId, question.getId());

            List<QuestionChoice> list1 = questionChoiceMapper.selectList(lambdaQueryWrapper);
            question.setChoices(list1);
            LambdaQueryWrapper<QuestionAnswer> lambdaQueryWrapper1 = new LambdaQueryWrapper<>();
            lambdaQueryWrapper1.eq(QuestionAnswer::getQuestionId, question.getId());
            QuestionAnswer questionAnswer = questionAnswerMapper.selectOne(lambdaQueryWrapper1);
            question.setAnswer(questionAnswer);
        }

        paper.setQuestions(list);

        return paper;


    }

    @Transactional(rollbackFor = Exception.class)
    public void createPaper(PaperVo paperVo) {
        Paper paper = new Paper();
        paper.setDescription(paperVo.getDescription());
        paper.setDuration(paperVo.getDuration());
        paper.setName(paperVo.getName());
        paper.setStatus("DRAFT");

        if (ObjectUtils.isEmpty(paperVo.getQuestions())) {
            paper.setQuestionCount(0);
            paper.setTotalScore(BigDecimal.valueOf(0));
            paperMapper.insert(paper);
        }
        paper.setQuestionCount(paperVo.getQuestions().size());
        paper.setTotalScore(paperVo.getQuestions().values().stream().reduce(BigDecimal.ZERO, BigDecimal::add));
        paperMapper.insert(paper);
        if (!ObjectUtils.isEmpty(paperVo.getQuestions())) {
            Map<Integer, BigDecimal> map = paperVo.getQuestions();
            for (Map.Entry entry : map.entrySet()) {

                PaperQuestion paperQuestion = new PaperQuestion();
                paperQuestion.setPaperId(Math.toIntExact(paper.getId()));
                paperQuestion.setQuestionId(Long.valueOf(entry.getKey().toString()));
                paperQuestion.setScore((BigDecimal) entry.getValue());

                paperQuestionMapper.insert(paperQuestion);

            }
        }


    }

    @Transactional(rollbackFor = Exception.class)
    public Paper aicreate(AiPaperVo aiPaperVo) {
        //基本信息保存
        Paper paper = new Paper();
        BeanUtils.copyProperties(aiPaperVo, paper);
        paper.setStatus("DRAFT");
        save(paper);
        //组卷规则下的试题选择和中间表保存
        int questionCount = 0;
        BigDecimal totalScore = BigDecimal.ZERO;
        for (RuleVo ruleVo : aiPaperVo.getRules()) {
            //数量为0跳过
            if (ruleVo.getCount() == 0) {
                continue;
            }
            //查询当前规则下的所有题目集合
            LambdaQueryWrapper<Question> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(Question::getType, ruleVo.getType().name());
            lambdaQueryWrapper.in(!ObjectUtils.isEmpty(ruleVo.getCategoryIds()), Question::getCategoryId, ruleVo.getCategoryIds());
            List<Question> alllist = questionMapper.selectList(lambdaQueryWrapper);
            if (ObjectUtils.isEmpty(alllist)) {
                continue;
            }

            //判断是否有规则下count数量，没有要全部
            int realNumbers = Math.min(ruleVo.getCount(), alllist.size());
            //规则数量和分数累加
            questionCount += realNumbers;
            totalScore = totalScore.add(BigDecimal.valueOf(realNumbers * ruleVo.getScore()));

            //打乱数据，截取需要题目数量
            Collections.shuffle(alllist);
            List<Question> reallist = alllist.subList(0, realNumbers);
            //转成中间表并保存
            List<PaperQuestion> paperQuestionList = reallist.stream().map(question -> new PaperQuestion(paper.getId().intValue(), question.getId(), BigDecimal.valueOf(ruleVo.getScore()))).collect(Collectors.toList());
            for (PaperQuestion paperQuestion : paperQuestionList) {
                paperQuestionMapper.insert(paperQuestion);
            }
        }
        paper.setQuestionCount(questionCount);
        paper.setTotalScore(totalScore);
        updateById(paper);
        return paper;

    }

    public void updatePaper(Integer id, PaperVo paperVo) {
        Paper paper=paperMapper.selectById(id);
        if(paper.getStatus().equals("PUBLISHED")){
            throw new BaseException("发布状态下的试卷不可编辑");

        }
        if(paper == null){
            throw new BaseException("试卷不存在");
        }
        BeanUtils.copyProperties(paperVo,paper);

        LambdaQueryWrapper<PaperQuestion> lambdaQueryWrapper=new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(PaperQuestion::getPaperId,id);
        List<PaperQuestion> list=paperQuestionMapper.selectList(lambdaQueryWrapper);
      for (PaperQuestion paperQuestion:list){
          paperQuestionMapper.deleteById(paperQuestion.getId());
      }
        BigDecimal totalScore = BigDecimal.ZERO;

       for (Map.Entry entry:paperVo.getQuestions().entrySet()){
           PaperQuestion paperQuestion=new PaperQuestion();
           paperQuestion.setPaperId(id);
           paperQuestion.setPaperId(Math.toIntExact(paper.getId()));
           paperQuestion.setQuestionId(Long.valueOf(entry.getKey().toString()));
           paperQuestion.setScore((BigDecimal) entry.getValue());
           paperQuestionMapper.insert(paperQuestion);

           totalScore=  totalScore.add(BigDecimal.valueOf(Long.parseLong(entry.getValue().toString())));
       }
       paper.setQuestionCount(paperVo.getQuestions().size());
       paper.setTotalScore(totalScore);
        paperMapper.updateById(paper);



    }

} 